// 倒药水游戏主逻辑（改进版）
import { UIController } from './ui.js';
import { AnimationSystem } from './animation.js';

class GameLogic {
    constructor() {
        this.gameState = {
            currentLevel: 1,
            score: 0,
            moves: 0,
            tubes: [],
            isGameComplete: false,
            hints: 3,
            helps: 3,
            emptyTubes: 1,
            undoStack: [],
            selectedTube: null
        };
        
        // 限制为4种颜色：红、黄、蓝、绿
        this.colors = ['red', 'yellow', 'blue', 'green'];
        this.ui = new UIController();
        this.animation = new AnimationSystem();
        
        // 将游戏实例暴露给全局，供UI事件使用
        window.gameInstance = this;
        
        this.init();
    }

    async init() {
        await this.ui.bindEvents(this);
        await this.initializeLevel(this.gameState.currentLevel);
        this.updateUI();
    }

    async initializeLevel(level) {
        const levelConfig = this.generateLevelConfig(level);
        this.gameState.tubes = [];
        this.gameState.moves = 0;
        this.gameState.selectedTube = null;
        this.gameState.undoStack = [];
        
        // 生成完整的试管（每种颜色4格）
        const colorsToUse = this.colors.slice(0, levelConfig.colorCount);
        const completeTubes = [];
        
        for (let i = 0; i < levelConfig.colorCount; i++) {
            const tube = {
                id: i,
                colors: new Array(4).fill(colorsToUse[i]),
                maxCapacity: 4,
                isEmpty: false,
                isComplete: true,
                hasBottleCap: false
            };
            completeTubes.push(tube);
        }
        
        // 打乱液体创建混合试管
        const mixedTubes = this.createMixedTubes(completeTubes, levelConfig.tubeCount);
        
        // 添加空试管
        for (let i = 0; i < levelConfig.emptyTubes; i++) {
            mixedTubes.push({
                id: mixedTubes.length,
                colors: [],
                maxCapacity: 4,
                isEmpty: true,
                isComplete: false,
                hasBottleCap: false
            });
        }
        
        this.gameState.tubes = mixedTubes;
        this.gameState.currentLevel = level;
        
        await this.ui.renderTubes(this.gameState.tubes);
        this.updateUI();
    }

    generateLevelConfig(level) {
        // 根据关卡调整难度，但颜色最多4种
        const colorCount = Math.min(2 + Math.floor(level / 2), 4);
        const tubeCount = Math.min(3 + Math.floor(level / 2), 8);
        const emptyTubes = Math.min(1 + Math.floor(level / 3), 3);
        
        return {
            colorCount,
            tubeCount: Math.max(tubeCount, colorCount + 1),
            emptyTubes,
            targetMoves: 15 + level * 3
        };
    }

    createMixedTubes(completeTubes, targetCount) {
        const allLiquids = [];
        
        // 收集所有液体
        completeTubes.forEach(tube => {
            allLiquids.push(...tube.colors);
        });
        
        // 打乱液体
        for (let i = allLiquids.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [allLiquids[i], allLiquids[j]] = [allLiquids[j], allLiquids[i]];
        }
        
        // 分配到试管中
        const mixedTubes = [];
        let liquidIndex = 0;
        
        for (let i = 0; i < targetCount && liquidIndex < allLiquids.length; i++) {
            const tube = {
                id: i,
                colors: [],
                maxCapacity: 4,
                isEmpty: false,
                isComplete: false,
                hasBottleCap: false
            };
            
            // 每个试管放入1-4层液体
            const layerCount = Math.min(4, allLiquids.length - liquidIndex);
            for (let j = 0; j < layerCount; j++) {
                tube.colors.push(allLiquids[liquidIndex++]);
            }
            
            tube.isEmpty = tube.colors.length === 0;
            tube.isComplete = this.checkTubeComplete(tube);
            mixedTubes.push(tube);
        }
        
        return mixedTubes;
    }

    async selectTube(tubeId) {
        const tube = this.gameState.tubes[tubeId];
        
        // 如果试管已完成且有瓶塞，不能选择
        if (tube.hasBottleCap) {
            await this.ui.showMessage('试管已封口，无法操作');
            return;
        }
        
        if (this.gameState.selectedTube === null) {
            // 选择源试管
            if (!tube.isEmpty) {
                this.gameState.selectedTube = tubeId;
                await this.ui.highlightTube(tubeId, true, 'selected');
                await this.animation.animateSelection(tubeId, true);
            } else {
                await this.ui.showMessage('空试管无法选择');
            }
        } else if (this.gameState.selectedTube === tubeId) {
            // 取消选择
            await this.ui.highlightTube(tubeId, false, 'selected');
            await this.animation.animateSelection(tubeId, false);
            this.gameState.selectedTube = null;
        } else {
            // 执行倒液体操作
            const success = await this.pourLiquid(this.gameState.selectedTube, tubeId);
            if (success) {
                // 取消选择状态
                await this.ui.highlightTube(this.gameState.selectedTube, false, 'selected');
                await this.animation.animateSelection(this.gameState.selectedTube, false);
                this.gameState.selectedTube = null;
                
                if (await this.checkWinCondition()) {
                    await this.handleWin();
                }
            } else {
                // 倒液体失败，显示目标试管高亮提示
                await this.ui.highlightTube(tubeId, true, 'target');
                await this.ui.showMessage('无法倒入，请选择其他试管');
                
                // 1秒后移除目标高亮
                setTimeout(async () => {
                    await this.ui.highlightTube(tubeId, false, 'target');
                }, 1000);
            }
        }
    }

    async pourLiquid(fromTubeId, toTubeId) {
        const fromTube = this.gameState.tubes[fromTubeId];
        const toTube = this.gameState.tubes[toTubeId];
        
        // 检查是否可以倒液体
        if (fromTube.isEmpty || toTube.colors.length >= toTube.maxCapacity) {
            return false;
        }
        
        // 检查目标试管是否已封口
        if (toTube.hasBottleCap) {
            return false;
        }
        
        const topColor = fromTube.colors[fromTube.colors.length - 1];
        
        // 检查颜色是否匹配（空试管或顶部颜色相同）
        if (!toTube.isEmpty && toTube.colors[toTube.colors.length - 1] !== topColor) {
            return false;
        }
        
        // 保存状态用于撤销
        this.saveStateForUndo();
        
        // 计算可以倒多少层
        let layersToPour = 0;
        for (let i = fromTube.colors.length - 1; i >= 0; i--) {
            if (fromTube.colors[i] === topColor && 
                toTube.colors.length + layersToPour < toTube.maxCapacity) {
                layersToPour++;
            } else {
                break;
            }
        }
        
        // 执行倒液体动画
        await this.animation.animatePour(fromTubeId, toTubeId);
        
        // 移动液体
        for (let i = 0; i < layersToPour; i++) {
            const color = fromTube.colors.pop();
            toTube.colors.push(color);
        }
        
        // 更新试管状态
        fromTube.isEmpty = fromTube.colors.length === 0;
        toTube.isEmpty = toTube.colors.length === 0;
        fromTube.isComplete = this.checkTubeComplete(fromTube);
        toTube.isComplete = this.checkTubeComplete(toTube);
        
        // 如果试管完成，添加瓶塞
        if (toTube.isComplete && !toTube.hasBottleCap) {
            toTube.hasBottleCap = true;
            setTimeout(async () => {
                await this.animation.animateBottleCap(toTubeId);
            }, 500);
        }
        
        // 更新移动次数
        this.gameState.moves++;
        
        // 重新渲染试管
        await this.ui.renderTubes(this.gameState.tubes);
        this.updateUI();
        
        // 检查是否有试管完成
        if (toTube.isComplete) {
            await this.animation.animateComplete(toTubeId);
        }
        
        return true;
    }

    checkTubeComplete(tube) {
        if (tube.isEmpty) return false;
        if (tube.colors.length !== tube.maxCapacity) return false;
        
        const firstColor = tube.colors[0];
        return tube.colors.every(color => color === firstColor);
    }

    async checkWinCondition() {
        return this.gameState.tubes.every(tube => 
            tube.isEmpty || tube.isComplete
        );
    }

    async getHint() {
        if (this.gameState.hints <= 0) {
            await this.ui.showMessage('没有提示次数了！');
            return;
        }

        const hint = this.findBestMove();
        if (hint) {
            this.gameState.hints--;
            await this.ui.showHint(hint.from, hint.to);
            this.updateUI();
        } else {
            await this.ui.showMessage('当前没有可用的移动！');
        }
    }

    findBestMove() {
        // 寻找最佳移动策略
        for (let fromId = 0; fromId < this.gameState.tubes.length; fromId++) {
            const fromTube = this.gameState.tubes[fromId];
            
            if (fromTube.isEmpty || fromTube.hasBottleCap) continue;
            
            const topColor = fromTube.colors[fromTube.colors.length - 1];
            
            for (let toId = 0; toId < this.gameState.tubes.length; toId++) {
                if (fromId === toId) continue;
                
                const toTube = this.gameState.tubes[toId];
                
                if (toTube.hasBottleCap || toTube.colors.length >= toTube.maxCapacity) continue;
                
                // 检查是否可以倒入
                if (toTube.isEmpty || toTube.colors[toTube.colors.length - 1] === topColor) {
                    return { from: fromId, to: toId };
                }
            }
        }
        
        return null;
    }

    saveStateForUndo() {
        const state = {
            tubes: JSON.parse(JSON.stringify(this.gameState.tubes)),
            moves: this.gameState.moves,
            score: this.gameState.score
        };
        this.gameState.undoStack.push(state);
        
        // 限制撤销栈大小
        if (this.gameState.undoStack.length > 10) {
            this.gameState.undoStack.shift();
        }
    }

    async undoMove() {
        if (this.gameState.undoStack.length === 0) {
            await this.ui.showMessage('没有可撤销的步骤！');
            return;
        }

        const previousState = this.gameState.undoStack.pop();
        this.gameState.tubes = previousState.tubes;
        this.gameState.moves = previousState.moves;
        this.gameState.score = previousState.score;
        this.gameState.selectedTube = null;

        await this.ui.renderTubes(this.gameState.tubes);
        this.updateUI();
        await this.ui.showMessage('已撤销上一步操作');
    }

    async addEmptyTube() {
        if (this.gameState.emptyTubes <= 0) {
            await this.ui.showMessage('没有空试管可添加！');
            return;
        }

        const newTube = {
            id: this.gameState.tubes.length,
            colors: [],
            maxCapacity: 4,
            isEmpty: true,
            isComplete: false,
            hasBottleCap: false
        };

        this.gameState.tubes.push(newTube);
        this.gameState.emptyTubes--;

        await this.ui.renderTubes(this.gameState.tubes);
        this.updateUI();
        await this.ui.showMessage('已添加一个空试管');
    }

    async resetGame() {
        this.gameState.selectedTube = null;
        await this.initializeLevel(this.gameState.currentLevel);
        await this.ui.showMessage('游戏已重置');
    }

    async nextLevel() {
        this.gameState.currentLevel++;
        this.gameState.selectedTube = null;
        await this.initializeLevel(this.gameState.currentLevel);
    }

    async handleWin() {
        this.gameState.isGameComplete = true;
        
        // 计算得分
        const levelBonus = this.gameState.currentLevel * 100;
        const moveBonus = Math.max(0, (50 - this.gameState.moves) * 10);
        const totalScore = levelBonus + moveBonus;
        this.gameState.score += totalScore;
        
        this.updateUI();
        
        // 延迟显示胜利对话框
        setTimeout(async () => {
            await this.ui.showWinDialog();
        }, 1000);
    }

    updateUI() {
        this.ui.updateLevel(this.gameState.currentLevel);
        this.ui.updateScore(this.gameState.score);
        this.ui.updateMoves(this.gameState.moves);
        this.ui.updateHints(this.gameState.hints);
        this.ui.updateEmptyTubes(this.gameState.emptyTubes);
    }
}

// 启动游戏
document.addEventListener('DOMContentLoaded', () => {
    new GameLogic();
});